package com.alibaba.sdk.service.impl;

import com.alibaba.sdk.annotation.BaseService;
import com.alibaba.sdk.constant.ApplicationErrorConstant;
import com.alibaba.sdk.enums.UserTypeEnum;
import com.alibaba.sdk.exception.BusinessException;
import com.alibaba.sdk.model.OperationResult;
import com.alibaba.sdk.model.assembler.UserAssembler;
import com.alibaba.sdk.model.dao.UserMapper;
import com.alibaba.sdk.model.dto.UserDTO;
import com.alibaba.sdk.model.entity.User;
import com.alibaba.sdk.model.input.OneUserInput;
import com.alibaba.sdk.model.input.UserAddInput;
import com.alibaba.sdk.model.input.UserListInput;
import com.alibaba.sdk.model.input.UserTypeInput;
import com.alibaba.sdk.model.output.OneUserResponse;
import com.alibaba.sdk.model.output.UserAddResponse;
import com.alibaba.sdk.model.output.UserListResponse;
import com.alibaba.sdk.model.query.UserListQuery;
import com.alibaba.sdk.service.UserService;
import com.alibaba.sdk.util.EncryptUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * 用户服务实现类
 *
 * @author Shawn(Shawn_0108 @ 163.com)
 * @version 1.0
 * @date 2020/6/4
 */
@Slf4j
@BaseService
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserAssembler userAssembler;

    /**
     * 用户列表翻页查询
     *
     * @param userListInput 列表查询参数类
     * @return
     */
    @Override
    public OperationResult<UserListResponse> userList(UserListInput userListInput) {
        // 数据库查询参数类
        UserListQuery userListQuery = new UserListQuery();
        BeanUtils.copyProperties(userListInput, userListQuery);

        // 数据库查询
        Page<UserDTO> listPage = userMapper.queryUserList(new Page(userListInput.getPageNum(), userListInput.getShowNum()), userListQuery);
        return OperationResult.success(new UserListResponse(listPage.getRecords(), listPage.getTotal(), listPage.getPages()));
    }

    /**
     * 用户新增
     *
     * @param userAddInput 用户新增参数类
     * @return
     */
    @Override
    public OperationResult<UserAddResponse> userAdd(UserAddInput userAddInput) {
        // 用户名重复校验
        LambdaQueryWrapper<User> duplicateUserQuery = new LambdaQueryWrapper<User>().eq(User::getUsername, userAddInput.getUsername());
        if (Objects.nonNull(userMapper.selectOne(duplicateUserQuery))) {
            log.warn("用户名重复");
            return OperationResult.failWithCode(ApplicationErrorConstant.USERNAME_DUPLICATE);
        }
        // 不能添加系统管理员
        if (UserTypeEnum.SUPER_ADMIN.equals(userAddInput.getUserType())) {
            log.warn("禁止添加系统管理员");
            return OperationResult.failWithCode(ApplicationErrorConstant.FORBID_ADD_SUPER_ADMIN);
        }

        // 准备新增实体类
        User user = new User();
        BeanUtils.copyProperties(userAddInput, user);
        user.setPassword(EncryptUtil.getEncryptPassword(userAddInput.getPassword()));
        // 新增用户
        int rows = userMapper.insert(user);
        if (rows != 1) {
            log.error("用户新增异常");
            return OperationResult.failWithCode(ApplicationErrorConstant.SYSTEM_ERROR_CODE);
        }
        return OperationResult.success(new UserAddResponse(user.getId()));
    }

    /**
     * 查看单条用户信息
     *
     * @param input 用户id
     * @return
     */
    @Override
    public OperationResult<OneUserResponse> getOne(OneUserInput input) {
        // 通过id查询用户信息
        User user = userMapper.selectById(input.getUserId());
        if (user == null) {
            throw new BusinessException("111111", "数据为空");
        }
        return OperationResult.success(userAssembler.fromEntity(user));
    }

    @Override
    public OperationResult<User> get(UserTypeInput input) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>().eq(User::getUserType, input.getUserType());
        return OperationResult.success(userMapper.selectOne(wrapper));
    }
}